package com.erp.erp_ui.Billing.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.erp.enums.ModuleTypeEnum;
import com.erp.erp_entitys.BillExchangeInfo.BillExchangeProductInfo;
import com.erp.erp_entitys.Billing.entity.BillingDetailEntity;
import com.erp.erp_entitys.Billing.entity.BillingEntity;
import com.erp.erp_entitys.Billing.req.*;
import com.erp.erp_entitys.Billing.vo.*;
import com.erp.erp_entitys.Cost.req.CostAnnexReq;
import com.erp.erp_entitys.Cost.vo.CostAnnexVO;
import com.erp.erp_entitys.Cost.vo.NameAndCodeVO;
import com.erp.erp_entitys.Cost.vo.QueryImportContractVO;
import com.erp.erp_entitys.Purchase.Purchase;
import com.erp.erp_entitys.business.entity.CarryDetailProductEntity;
import com.erp.erp_entitys.business.entity.ExportContractEntity;
import com.erp.erp_entitys.warehouse.entity.AnnexEntity;
import com.erp.erp_servers.Billing.BillingDetailService;
import com.erp.erp_servers.Billing.BillingService;
import com.erp.erp_servers.Purchase.IPurchaseService;
import com.erp.erp_servers.bill_exchange.BillExchangeProductInfoService;
import com.erp.erp_servers.business.ICarryDetailProductService;
import com.erp.erp_servers.business.IExportContractService;
import com.erp.erp_servers.warehouse.IAnnexService;
import com.erp.utils.DateUtils;
import com.erp.utils.R;
import com.erp.utils.ResultStatusEnum;
import com.erp.utils.StringUtil;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zjk
 * @version 1.0
 * @description
 * @date 2021/1/16/016 23:09
 */
@Service
public class BillingAllService {
    /**
     * 日志
     */
    private static final Logger log= LoggerFactory.getLogger(BillingAllService.class);
    /**
     * 开票主信息接口
     */
    private final BillingService billingService;
    /**
     * 开票明细信息接口
     */
    private final BillingDetailService billingDetailService;

    /**
     * 添加附件接口
     */
    private final AnnexService annexServices;
    /**
     * 查询附件接口
     */
    private final IAnnexService annexService;

    /**
     * 采购主信息接口
     */
    private final IPurchaseService purchaseService;

    /**
     * 外销主信息接口
     */
    private final IExportContractService exportContractService;

    /**
     * 结汇产品接口
     */
    private final BillExchangeProductInfoService productService;

    /**
     * 出运明细产品接口
     */
    private final ICarryDetailProductService carryDetailProductService;

    public BillingAllService(BillingService billingService,
                             BillingDetailService billingDetailService,
                             AnnexService annexServices, IAnnexService annexService, IPurchaseService purchaseService, IExportContractService exportContractService, BillExchangeProductInfoService productService, ICarryDetailProductService carryDetailProductService) {
        this.billingService = billingService;
        this.billingDetailService = billingDetailService;
        this.annexServices = annexServices;
        this.annexService = annexService;
        this.purchaseService = purchaseService;
        this.exportContractService = exportContractService;
        this.productService = productService;
        this.carryDetailProductService = carryDetailProductService;
    }


    /**
     * 返回报关明细表中的数量-开票表里的数量大于0的报关产品信息
     * 返回符合条件的报关明细信息
     * @return
     */
    public PageInfo<QueryBillDeclareDetailVO> findBillDeclareDetailByPage(Integer declareId,String manufacturerName,String invoiceCode){

        //根据报关主id获取报关明细信息集合
        List<QueryBillDeclareDetailVO> billDeclareDetailList=billingService.selectBillDeclareProductByDeclareId(declareId,manufacturerName);

        //直接转换成Iterator
        Iterator<QueryBillDeclareDetailVO> iterator=billDeclareDetailList.iterator();

        //循环移除未开票数量小于0的记录
        while (iterator.hasNext()){
            QueryBillDeclareDetailVO bdv=iterator.next();

            //获取已开票数量
            Integer num=billingService.selectInvoicedQuantity(manufacturerName,invoiceCode,bdv.getStockCode(),bdv.getGoodsCode(),bdv.getSpecCode());
            if (num!=null){
                int flagNum=bdv.getGoodsNum()-num;
                if(flagNum<=0){
                    iterator.remove();
                }else {
                    bdv.setCanBillingAmount(flagNum);
                }
            }else {
                //如果num为空，这个单子没有开票过，此时可以开票的数量就是报关产品的数量
                bdv.setCanBillingAmount(bdv.getGoodsNum());
            }
        }

        PageInfo pageInfo=new PageInfo(billDeclareDetailList);
        return pageInfo;
    }




    /**
     * 返回出运明细产品表中的数量-开票表里的数量大于0的出运明细产品信息
     * 返回符合条件的出运明细产品信息
     * @return
     */
    public PageInfo<QueryImportCarrDetailProductRes> findCarryDetailProductList(QueryImportCarrDetailProductReq req){

        List<QueryImportCarrDetailProductRes> productList1 = billingService.findCarryDetailProductList(req);

        Iterator<QueryImportCarrDetailProductRes> iterator1=productList1.iterator();
        //循环移除未开票数量小于0的记录
        while (iterator1.hasNext()){
            QueryImportCarrDetailProductRes bdv=iterator1.next();
            //获取已开票数量
            Integer num=billingService.findCarryDetailProductQuantity(req.getSourceType(),bdv.getBillNo(),bdv.getSaleContractNo(),bdv.getProductCode(),bdv.getSpecNo());

            if (num!=null){
                BigDecimal numBig=new BigDecimal(num);
                BigDecimal subtract=bdv.getProductNum().subtract(numBig);
                //如果差数比0大，则表示总数量比开票数量大，则直接将差数填进去
                if (subtract.compareTo(BigDecimal.ZERO)==1){
                    bdv.setCanBillingAmount(subtract);
                }else{//小于0或者等于0，总数量小于开票数量，则去掉当前采购产品
                    iterator1.remove();
                }
            }else {
                //如果num为空，这个单子没有开票过，此时可以开票的数量就是产品的数量
                bdv.setCanBillingAmount(bdv.getProductNum());
            }
        }
        PageInfo pageInfo=new PageInfo(productList1);
        return pageInfo;
    }




    /**
     * 修改，添加开票信息
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean add(InsertBillingReq req){
            Integer billingId=req.getId();
            if (StringUtils.isEmpty(req.getIsViewFile())) {

                //1：保存，2：提交
                BillingEntity billingEntity = new BillingEntity();
                BeanUtils.copyProperties(req, billingEntity);

                BillingEntity oldBilling = billingService.selectBillingByCode(req.getCode());

                //操作1：新增，2：修改
                //添加
                if (req.getSetType() == 1) {
                    //开票信息状态
                    billingEntity.setStatus(1);
                    //开票信息有效
                    billingEntity.setValid(1);
                    if (oldBilling != null) {//单号重复，重新生成单号
                        String code=billingService.selectCodeByCode();
                        billingEntity.setCode(code);
                    }

                    //添加开票主信息
                    Integer num = billingService.insertBillingEntity(billingEntity);
                    if (num == 1) {
                        billingId=billingEntity.getId();
                    }
                }

                //修改
                if (req.getSetType() == 2) {
                    billingEntity.setStatus(1);
                    billingEntity.setValid(1);
                    billingService.updateBillingEntityByCode(billingEntity);
                    BillingEntity tempEntity = billingService.selectBillingByCode(req.getCode());
                    billingId = tempEntity.getId();
                }

                if (billingId==null){
                    return false;
                }

                //获取传进来的开票明细集合
                List<InsertBillingDetailReq> billingDetailReqs = req.getBillingDetailReqList();
                List<BillingDetailEntity> newBillingDetailEntityList = new ArrayList<>(billingDetailReqs.size() + 5);
                for (InsertBillingDetailReq bdReq : billingDetailReqs) {
                    BillingDetailEntity bd = new BillingDetailEntity();
                    //填充数据

                    bd.setId(bdReq.getDeclareProductId());
                    bd.setBillingId(bdReq.getDeclareId());
                    bd.setImg(bdReq.getImg());
                    bd.setContractCode(bdReq.getSaleContractCode());
                    bd.setPurchaseOrderCode(bdReq.getStockCode());
                    bd.setProductCode(bdReq.getGoodsCode());
                    bd.setSpecificationCode(bdReq.getSpecCode());
                    bd.setSpecificationDesc(bdReq.getGoodsSpec());
                    bd.setCustomerArticleCode(bdReq.getCustomerArticleCode());//
                    bd.setCustomerContractCode(bdReq.getClientContractNo());
                    bd.setChineseName(bdReq.getGoodsCname());
                    bd.setChineseDesc(bdReq.getGoodsCdesc());
                    bd.setEnglishName(bdReq.getGoodsEname());
                    bd.setEnglishDesc(bdReq.getGoodsEdesc());

                    bd.setNumber(bdReq.getGoodsNum());
                    bd.setGoodsUnit(bdReq.getGoodsUnit());
                    bd.setUnitPrice(bdReq.getInvoiceUnitPrice());
                    bd.setSubtotal(bdReq.getInvoiceSubtotal());
                    bd.setColor(bdReq.getColor());
                    bd.setGrossWeight(bdReq.getGoodsGross());
                    bd.setSubtotalOfGrossWeight(bdReq.getTotalGross());
                    bd.setNetWeight(bdReq.getNetWeight());
                    bd.setSubtotalOfNetWeight(bdReq.getTotalNet());
                    bd.setPurchaseUnitPrice(bdReq.getPurchaseUnitPrice());
                    bd.setUnitCost(bdReq.getUnitCost());
                    bd.setCostSubtotal(bdReq.getCostSubtotal());
                    bd.setSupplierName(bdReq.getSupplyName());
                    bd.setSupplierCode(bdReq.getSupplyCode());
                    bd.setDeclarationUnitPrice(bdReq.getDeclarePrice());
                    bd.setSubtotalOfDeclarationAmount(bdReq.getTotalPrice());
                    bd.setProductType(bdReq.getProductType());
                    bd.setCustomsCode(bdReq.getHsCode());
                    bd.setDeclarationProductChineseName(bdReq.getBillGoodsCname());
                    bd.setDeclarationProductEnglishName(bdReq.getBillGoodsEname());
                    bd.setEssentialFactor(bdReq.getHsMemo());
                    bd.setVatRate(bdReq.getAddRate());
                    bd.setTaxRebateRate(bdReq.getBackRate());
                    bd.setVolume(bdReq.getBulk());
                    bd.setInvoiceType(bdReq.getInvoiceType());
                    bd.setCustomerInvoiceGoodsName(bdReq.getCustomerInvoiceGoodsName());
                    bd.setCustomerInvoiceSpecModel(bdReq.getCustomerInvoiceSpecModel());
                    bd.setCustomerMaterialsCode(bdReq.getCustomerMaterialsCode());

                    newBillingDetailEntityList.add(bd);
                }
                //添加开票明细
                if (req.getSetType() == 1) {
                    for (BillingDetailEntity billingDetailEntity : newBillingDetailEntityList) {
                        //设置开票id
                        billingDetailEntity.setBillingId(billingId);
                        billingDetailEntity.setValid(1);
                        //添加开票明细
                        billingDetailService.insertBillingDetailEntity(billingDetailEntity);
                    }

                }
                //修改开票明细
                if (req.getSetType() == 2) {
                    List<BillingDetailEntity> oldBillingDetailList = billingDetailService.selectByBillingDetailBillingId(billingId);
                    //获取旧明细ID集合
                    List<Integer> oldIds = oldBillingDetailList.stream().map(p -> p.getId()).collect(Collectors.toList());
                    //获取新明细ID集合
                    List<Integer> newIds = newBillingDetailEntityList.stream().map(p -> p.getId()).collect(Collectors.toList());
                    if (newIds.size() != 0) {
                        //获得删除的元素
                        oldIds.removeAll(newIds);
                    }

                    //删除,已经删除的元素
                    if (oldIds.size() != 0) {
                        billingDetailService.delete(oldIds);
                    }


                    for (BillingDetailEntity newDetail : newBillingDetailEntityList) {
                        newDetail.setBillingId(billingId);
                        if (newDetail.getId() == null) {
                            billingDetailService.insertBillingDetailEntity(newDetail);
                        } else {
                            billingDetailService.updateByBillingDetail(newDetail);
                        }

                    }
                }
            }
            //附件
            List<CostAnnexReq> newAnnexReqs=req.getAnnexReqs();

            Integer moduleId=ModuleTypeEnum.MONEY_RECEIVE_BILLING.getId();
            boolean flag =  annexServices.addAnnex(newAnnexReqs,billingId,moduleId,req.getOperatorName(), req.getOperatorCode(),req.getSetType());
            annexServices.deleteTempAnnex(newAnnexReqs);
            if(flag){
                return true;
            }

            return false;
    }


    /**
     * 根据开票id查询开票，开票明细，附件。信息
     * @param billingId
     * @return
     */
    public MergeBillingVO findAllBillingById(Integer billingId){
        MergeBillingVO mergeBilling=new MergeBillingVO();

        //开票主信息
        BillingEntity billingEntity=billingService.selectById(billingId);
        BeanUtils.copyProperties(billingEntity,mergeBilling);
        mergeBilling.setBillingDate(DateUtils.format(billingEntity.getBillingDate(), DateUtils.DATE_PATTERN));
        mergeBilling.setCreateDate(DateUtils.format(billingEntity.getCreateDate(), DateUtils.DATE_PATTERN));
        mergeBilling.setContactName(billingEntity.getContactName());


        //开票明细
        List<BillingDetailEntity> billingDetailEntityList=billingDetailService.selectByBillingId(billingId);
        List<InsertBillingDetailReq> billDeclareDetailList=new ArrayList<>();
        //复制数据
        for (BillingDetailEntity bd:billingDetailEntityList){
            InsertBillingDetailReq bdd=new InsertBillingDetailReq();

            //报关发票号
            bdd.setDeclarationInvoiceCode(billingEntity.getDeclarationInvoiceCode());
            //联系人
            bdd.setLinker(billingEntity.getContactName());
            //开票银行
            bdd.setBankName(billingEntity.getBankName());
            //开票抬头
            bdd.setCompanyName(billingEntity.getBillingTowerHeadName());
            bdd.setCompanyCode(billingEntity.getBillingTowerHeadCode());

            bdd.setDeclareProductId(bd.getId());
            bdd.setDeclareId(bd.getBillingId());
            bdd.setGoodsCode(bd.getProductCode());
            bdd.setSpecCode(bd.getSpecificationCode());
            bdd.setGoodsSpec(bd.getSpecificationDesc());
            bdd.setGoodsCname(bd.getChineseName());
            bdd.setGoodsEname(bd.getEnglishName());
            bdd.setGoodsCdesc(bd.getChineseDesc());
            bdd.setGoodsEdesc(bd.getEnglishDesc());
            bdd.setGoodsNum(bd.getNumber());
            bdd.setGoodsUnit(bd.getGoodsUnit());
            bdd.setInvoiceUnitPrice(bd.getUnitPrice());
            bdd.setInvoiceSubtotal(bd.getSubtotal());
            //剩余数量，页面没有
//            bdd.setLastAmount();
            bdd.setDeclarePrice(bd.getDeclarationUnitPrice());
            bdd.setTotalPrice(bd.getCostSubtotal());
            bdd.setUnitCost(bd.getUnitCost());
            bdd.setCostSubtotal(bd.getCostSubtotal());
            bdd.setStockCode(bd.getPurchaseOrderCode());
            bdd.setSaleContractCode(bd.getContractCode());
            bdd.setColor(bd.getColor());
            bdd.setGoodsGross(bd.getGrossWeight());
            bdd.setTotalGross(bd.getSubtotalOfGrossWeight());
            bdd.setNetWeight(bd.getNetWeight());
            bdd.setTotalNet(bd.getSubtotalOfNetWeight());
            bdd.setBulk(bd.getVolume());
//            bdd.setSupplyId(bd.getSupplierCode());
            bdd.setSupplyName(bd.getSupplierName());
//            报关发票号码，页面没有
//            bdd.setInvoiceCode();
//            联系人
//            bdd.setLinker();
            bdd.setProductType(bd.getProductType());
            bdd.setHsCode(bd.getCustomsCode());
            bdd.setBillGoodsCname(bd.getDeclarationProductChineseName());
            bdd.setBillGoodsEname(bd.getDeclarationProductEnglishName());
            bdd.setHsMemo(bd.getEssentialFactor());
            bdd.setAddRate(bd.getVatRate());
            bdd.setBackRate(bd.getTaxRebateRate());
            bdd.setClientContractNo(bd.getCustomerContractCode());
//            签约公司名称（开票抬头）
//            bdd.setCompanyCode();
//            bdd.setCompanyName();

            bdd.setInvoiceType(bd.getInvoiceType());

            bdd.setCustomerInvoiceGoodsName(bd.getCustomerInvoiceGoodsName());
            bdd.setCustomerInvoiceSpecModel(bd.getCustomerInvoiceSpecModel());
            bdd.setCustomerMaterialsCode(bd.getCustomerMaterialsCode());

            billDeclareDetailList.add(bdd);
        }
        mergeBilling.setBillingDetailList(billDeclareDetailList);

        //获取附件详情
        AnnexEntity annexEntity = new AnnexEntity();
        annexEntity.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_BILLING.getId());
        annexEntity.setParentId(billingEntity.getId());
        List<AnnexEntity> annexList = annexService.queryAll(annexEntity);

        List<CostAnnexVO> annexVos=new ArrayList<>();
        if (annexList.size()>0) {
            for (AnnexEntity annex : annexList) {
                CostAnnexVO annexVo = new CostAnnexVO();
                //赋值
                BeanUtils.copyProperties(annex, annexVo);
                //上传时间转换
                annexVo.setUploadTime(DateUtils.format(annex.getUploadTime(), DateUtils.DATE_TIME_PATTERN));
                //设置附件为旧附件,用以区分修改时附件状态
                annexVo.setNews(0);
                annexVos.add(annexVo);
            }
        }
        mergeBilling.setAnnexList(annexVos);
        return mergeBilling;
    }


    @Transactional(rollbackFor = Exception.class)
    public void updateBillingAndDetailValidById(Integer[] costIds){
        billingService.updateBillingValidById(costIds);
        billingDetailService.updateBillingDetailInvalidByBillingId(0,costIds);
    }
    /**
     * 计算符合 供应商 开票的采购产品
     * @param purchaseId
     * @return
     */
    public List<QueryPurchaseProductVO> selectPurchaseProductByPurchaseId(Integer purchaseId){
        List<QueryPurchaseProductVO> productVOList=billingService.selectPurchaseProductByPurchaseId(purchaseId);
        Purchase purchase=purchaseService.selectInfoById(purchaseId);
        Iterator iterator=productVOList.iterator();
        while (iterator.hasNext()){
            QueryPurchaseProductVO purchaseProduct= (QueryPurchaseProductVO) iterator.next();
            //根据采购单号，产品编码，规格编码。获取开票表实体
            if (purchase!=null){
                //采购单号，产品编码，
                Integer num=billingDetailService.findBillingDetailByParam(1,2,purchaseProduct.getSalesContractNo(),purchase.getPurchaseOrderNo(),purchaseProduct.getProductNo());

                if (num!=null){
                    //开票已存在的数量
                    BigDecimal billingNum=new BigDecimal(num);
                    //采购产品总数量
                    BigDecimal ppAmount=purchaseProduct.getAmount();
                    //采购总数量-已开票数量=可以开票数量
                    BigDecimal subtract=ppAmount.subtract(billingNum);
                    //如果差数比0大，则表示总数量比开票数量大，则直接将差数填进去
                    if (subtract.compareTo(BigDecimal.ZERO)==1){
                        purchaseProduct.setAmount(subtract);
                    }else{//小于0或者等于0，总数量小于开票数量，则去掉当前采购产品
                        iterator.remove();
                    }
                }


            }

        }

        return productVOList;
    }

    /**
     * 计算符合开票的外销产品信息
     * @param exportContractNo
     * @return
     */
    public List<QueryExportProductVO> selectExportProductByPurchaseId(String exportContractNo){
        ExportContractEntity entity=exportContractService.queryByBillNo(exportContractNo);
        List<QueryExportProductVO> productVOList=billingService.selectExportProductByPurchaseId(entity.getId());

        Iterator iterator=productVOList.iterator();
        while (iterator.hasNext()){
            QueryExportProductVO product= (QueryExportProductVO) iterator.next();
            product.setPurchaseType("1");


            //根据外销合同号，产品编码，规格编码。获取开票表实体
            if (entity!=null){
                Integer num=billingDetailService.findBillingDetailByParam(2,3,entity.getBillNo(),product.getPurchaseOrderNo(),product.getProductNo());
                if (num!=null){
                    //开票已存在的数量
                    BigDecimal billingNum=new BigDecimal(num);
                    //采购产品总数量
                    BigDecimal ppAmount=product.getAmount();
                    BigDecimal subtract=ppAmount.subtract(billingNum);
                    //如果差数比0大，则表示总数量比开票数量大，则直接将差数填进去
                    if (subtract.compareTo(BigDecimal.ZERO)==1){
                        product.setAmount(subtract);
                    }else{//小于0或者等于0，总数量小于开票数量，则去掉当前采购产品
                        iterator.remove();
                    }
                }


            }

        }

        return productVOList;
    }

    /**
     * 查询符合开票的结汇产品信息
     * @return
     */
    public List<QueryExportProductVO> selectBillExchangeProductByParam(String invoiceNo,Integer billId){
        BillExchangeProductInfo p=new BillExchangeProductInfo();
        p.setBillId(billId);
        List<BillExchangeProductInfo> billList=productService.queryAll(p);
        List<QueryExportProductVO> voList=new ArrayList<>();
        Iterator iterator=billList.iterator();
       A: while (iterator.hasNext()){
            BillExchangeProductInfo pro=(BillExchangeProductInfo)iterator.next();
            QueryExportProductVO vo=new QueryExportProductVO();

            vo.setProductNo(pro.getGoodsCode());
            vo.setSpecNo(pro.getSpecCode());
            vo.setNormExplain(pro.getGoodsSpec());
            vo.setChineseName(pro.getGoodsCname());
            vo.setEnglishName(pro.getGoodsEname());
            vo.setChineseDesc(pro.getGoodsCdesc());
            vo.setEnglishDesc(pro.getGoodsEdesc());
//            vo.setAmount(pro.getGoodsNum());
            vo.setUnit(pro.getGoodsUnit());
            vo.setPrice(pro.getFunitprice());
            vo.setColour(pro.getColor());
            vo.setVolume(pro.getBulk());
            vo.setPurchaseOrderNo(pro.getStockNo());
            vo.setPurchaseType("1");



            Integer num=billingDetailService.findBillingDetailByParamBillExchange(invoiceNo,invoiceNo,pro.getGoodsCode());
            if (num!=null){
                //开票已存在的数量
                BigDecimal billingNum=new BigDecimal(num);
                //采购产品总数量
                BigDecimal ppAmount=pro.getGoodsNum();
                BigDecimal subtract=ppAmount.subtract(billingNum);
                //如果差数比0大，则表示总数量比开票数量大，则直接将差数填进去
                if (subtract.compareTo(BigDecimal.ZERO)==1){
                    vo.setAmount(subtract);
                }else{//小于0或者等于0，总数量小于开票数量，则去掉当前采购产品
                    iterator.remove();
                    continue A;
                }
            }else{
                vo.setAmount(pro.getGoodsNum());
            }
            BigDecimal pri=null;
            if (vo.getPrice()==null){
                pri=new BigDecimal(0);
            }else {
                pri=vo.getPrice();
            }

            BigDecimal nu=null;
            if (vo.getAmount()==null){
                nu=new BigDecimal(0);
            }else {
                nu=vo.getAmount();
            }
            BigDecimal su=pri.multiply(nu);
            vo.setSubtotal(su);

            voList.add(vo);
        }
        return voList;
    }

    /**
     * 获取String类型不为空数据
     *
     * @param value 目标数据
     * @return 不为空数据
     */
    private String getNotNullOfStringInfo(String value) {
        if (StringUtils.isEmpty(value)) {
            return "";
        } else {
            return value;
        }
    }

    /**
     * 获取BigDecimal类型不为空的数据
     *
     * @param value 目标数据
     * @return 不为空数据
     */
    private BigDecimal getNotNullOfBigDecimalInfo(BigDecimal value) {
        if (StringUtil.isNotEmpty(value)) {
            return value;
        } else {
            return new BigDecimal("0");
        }
    }
    /**
     * 开票情况统计-分页
     * @param req
     * @return
     */
    public PageInfo<billingStatistics1VO> billingStatistics1List(billingStatistics1Req req) {
        List<billingStatistics1VO> billingStatistics1VOList=billingService.billingStatistics1List(req);
        PageInfo pageInfo=new PageInfo(billingStatistics1VOList);
        return pageInfo;
    }

    /**
     * 开票情况统计-导出
     * @param req
     * @return
     */
    public JSONObject billingStatistics1Export(billingStatistics1Req req){
        List<billingStatistics1VO> billingStatistics1VOList=billingService.billingStatistics1List(req);
        JSONObject obj = new JSONObject();
        //获取excel的title信息
        JSONArray titleList = getTitleCollectionFirstInfo(req);
        JSONArray data = new JSONArray();
        data.add(titleList);
        if (CollectionUtils.isEmpty(billingStatistics1VOList)) {
            obj.put("data", data);
            return obj;
        }
        excelCollectionFirstInfoExport(data, billingStatistics1VOList);
        obj.put("data", data);
        return obj;
    }
    private JSONArray getTitleCollectionFirstInfo(billingStatistics1Req req) {
        JSONArray obj = new JSONArray();
        obj.add("序号");
        obj.add("采购单号");
        obj.add("外销合同号");
        if (req.getSourceType()==1){
            obj.add("报关发票号");
        }else if (req.getSourceType()==2){
            obj.add("外销合同号");
        }
        obj.add("产品编码");
        obj.add("规格编码");
        obj.add("开票数量");
        obj.add("开票单价");
        obj.add("开票金额小计");
        if (req.getSourceType()==1){
            obj.add("厂商名称");
        }else if (req.getSourceType()==2){
            obj.add("客户名称");
        }
        obj.add("币种");
        obj.add("创建日期");
        obj.add("开票日期");
        if (req.getSourceType()==1){
            obj.add("报关产品数量");
        }else if (req.getSourceType()==2){
            obj.add("外销产品数量");
        }
        obj.add("需开票金额");
        obj.add("未开票金额");
        obj.add("产品类型");
        return obj;
    }

    private void excelCollectionFirstInfoExport(JSONArray data,List<billingStatistics1VO> list){
        //开票数量
        Integer number = 0;
        //开票单价
        BigDecimal unitPrice = new BigDecimal("0");
        //开票金额小计
        BigDecimal subtotal = new BigDecimal("0");
        //报关产品数量
        Integer goodsNum = 0;
        //需开票金额
        BigDecimal amountInvoiced = new BigDecimal("0");
        //未开票金额
        BigDecimal notAmountInvoiced = new BigDecimal("0");




        //申请金额
        BigDecimal applicationAmount = new BigDecimal("0");

        int i = 0;
        for (billingStatistics1VO vo : list) {
            JSONArray infoList = new JSONArray();
            infoList.add(++i);
            infoList.add(getNotNullOfStringInfo(vo.getPurchaseOrderCode()));
            infoList.add(getNotNullOfStringInfo(vo.getContractCode()));
            infoList.add(getNotNullOfStringInfo(vo.getDeclarationInvoiceCode()));
            infoList.add(getNotNullOfStringInfo(vo.getProductCode()));
            infoList.add(getNotNullOfStringInfo(vo.getSpecificationCode()));
            infoList.add(vo.getNumber());
            infoList.add(getNotNullOfBigDecimalInfo(vo.getUnitPrice()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getSubtotal()));
            infoList.add(getNotNullOfStringInfo(vo.getSupplierName()));
            infoList.add(getNotNullOfStringInfo(vo.getCurrencyName()));
            infoList.add(getNotNullOfStringInfo(vo.getCreateDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getBillingDateStr()));
            infoList.add(vo.getGoodsNum());
            infoList.add(getNotNullOfBigDecimalInfo(vo.getAmountInvoiced()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getNotAmountInvoiced()));
            infoList.add(getNotNullOfStringInfo(vo.getProductType()));

            if (vo.getNumber()!=null) {
                number = number+vo.getNumber();
            }
            if (StringUtil.isNotEmpty(vo.getUnitPrice())) {
                unitPrice = unitPrice.add(vo.getUnitPrice());
            }
            if (StringUtil.isNotEmpty(vo.getSubtotal())) {
                subtotal = subtotal.add(vo.getSubtotal());
            }
            if (StringUtil.isNotEmpty(vo.getAmountInvoiced())) {
                amountInvoiced = amountInvoiced.add(vo.getAmountInvoiced());
            }
            if (vo.getGoodsNum()!=null) {
                goodsNum = goodsNum+vo.getGoodsNum();
            }
            if (StringUtil.isNotEmpty(vo.getAmountInvoiced())) {
                amountInvoiced = amountInvoiced.add(vo.getAmountInvoiced());
            }
            if (StringUtil.isNotEmpty(vo.getNotAmountInvoiced())) {
                notAmountInvoiced = notAmountInvoiced.add(vo.getNotAmountInvoiced());
            }
            data.add(infoList);
        }
        //合计
        JSONArray titleList = new JSONArray();
        titleList.add("合计");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add(number);
        titleList.add(unitPrice);
        titleList.add(subtotal);
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add(goodsNum);
        titleList.add(amountInvoiced);
        titleList.add(notAmountInvoiced);
        titleList.add("");

        data.add(titleList);
    }
    /**
     * 采购开票统计-分页
     * @param req
     * @return
     */
    private List<BillingPurchaseStatisticsRes> billingPurchaseStatisticsList(BillingPurchaseStatisticsReq req){
        List<BillingPurchaseStatisticsRes> list=billingService.billingPurchaseStatisticsList(req);
        for (BillingPurchaseStatisticsRes p:list){
            p.setBillingDateStr(DateUtils.format(p.getBillingDate(),DateUtils.DATE_PATTERN));
            p.setCreateDateStr(DateUtils.format(p.getCreateDate(),DateUtils.DATE_PATTERN));
        }
        return list;
    }

    /**
     * 采购开票统计-分页
     * @param req
     * @return
     */
    public PageInfo<BillingPurchaseStatisticsRes> billingPurchaseStatisticsPage(BillingPurchaseStatisticsReq req){
        List<BillingPurchaseStatisticsRes> list=billingPurchaseStatisticsList(req);
        PageInfo pageInfo=new PageInfo(list);
        return pageInfo;
    }

    /**
     * 采购开票统计-导出
     * @param req
     * @return
     */
    public JSONObject billingPurchaseStatisticsExport(BillingPurchaseStatisticsReq req){
        List<BillingPurchaseStatisticsRes> list=billingPurchaseStatisticsList(req);
        JSONObject obj = new JSONObject();
        //获取excel的title信息
        JSONArray titleList = getTitleBillingPurchaseInfo();
        JSONArray data = new JSONArray();
        data.add(titleList);
        if (CollectionUtils.isEmpty(list)) {
            obj.put("data", data);
            return obj;
        }
        excelBillingPurchaseExport(data, list);
        obj.put("data", data);
        return obj;
    }
    private JSONArray getTitleBillingPurchaseInfo() {
        JSONArray obj = new JSONArray();
        obj.add("序号");
        obj.add("厂商名称");
        obj.add("发票收到日期");
        obj.add("报关发票号");
        obj.add("开票总额");
        obj.add("已开金额");
        obj.add("未开金额");
        obj.add("系统创建日期");
        obj.add("开票抬头");
        obj.add("操作员");
        obj.add("增票号");
        obj.add("报关单号");
        obj.add("备注");
        return obj;
    }


    private void excelBillingPurchaseExport(JSONArray data,List<BillingPurchaseStatisticsRes> list){
        //开票总额
        BigDecimal totalInvoicedAmount = new BigDecimal("0");
        //已开金额
        BigDecimal openedAmount = new BigDecimal("0");
        //未开金额
        BigDecimal uncommittedAmount = new BigDecimal("0");
        int i = 0;
        for (BillingPurchaseStatisticsRes vo : list) {
            JSONArray infoList = new JSONArray();
            infoList.add(++i);
            infoList.add(getNotNullOfStringInfo(vo.getManufacturerName()));
            infoList.add(getNotNullOfStringInfo(vo.getBillingDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getInvoiceCode()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getTotalInvoicedAmount()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getOpenedAmount()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getUncommittedAmount()));
            infoList.add(getNotNullOfStringInfo(vo.getCreateDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getBillingTowerHeadName()));
            infoList.add(getNotNullOfStringInfo(vo.getOperatorName()));
            infoList.add(getNotNullOfStringInfo(vo.getIncreaseCode()));
            infoList.add(getNotNullOfStringInfo(vo.getBillDeclareInvoiceNo()));
            infoList.add(getNotNullOfStringInfo(vo.getDescription()));
            if (StringUtil.isNotEmpty(vo.getTotalInvoicedAmount())) {
                totalInvoicedAmount = totalInvoicedAmount.add(vo.getTotalInvoicedAmount());
            }
            if (StringUtil.isNotEmpty(vo.getOpenedAmount())) {
                openedAmount = openedAmount.add(vo.getOpenedAmount());
            }
            if (StringUtil.isNotEmpty(vo.getUncommittedAmount())) {
                uncommittedAmount = uncommittedAmount.add(vo.getUncommittedAmount());
            }
            data.add(infoList);
        }
        //合计
        JSONArray titleList = new JSONArray();
        titleList.add("合计");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add(totalInvoicedAmount);
        titleList.add(openedAmount);
        titleList.add(uncommittedAmount);
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        data.add(titleList);
    }


    /**
     * 获取外销合同--开票用
     * @return
     */
    public PageInfo<QueryImportContractVO> getExportContentListByPage(QueryImportExportContractReq req){
        List<QueryImportContractVO> importContractVOS=billingService.getExportContentList(req);
        for (QueryImportContractVO p:importContractVOS){
            p.setSigningDateStr(DateUtils.format(p.getSigningDate(),DateUtils.DATE_PATTERN));
        }
        PageInfo pageInfo=new PageInfo(importContractVOS);
        return pageInfo;
    }


    /**
     * 获取价格术语，只包含国内的--开票用
     * @return
     */
    public List<NameAndCodeVO> getPriceTerms(){
        List<NameAndCodeVO> nameAndCodeList = billingService.getPriceTerms();
        return nameAndCodeList;
    }

    /**
     * 开票-导入采购合同
     * @param req
     * @return
     */
   public PageInfo<QueryPurchaseContractVO> getPurchaseContractListByPage(QueryPurchaseContractReq req){
       List<QueryPurchaseContractVO> purchaseContractList = billingService.getPurchaseContractList(req);
       for (QueryPurchaseContractVO p:purchaseContractList){
           p.setSigningDateStr(DateUtils.format(p.getSigningDate(),DateUtils.DATE_PATTERN));
       }
       PageInfo pageInfo=new PageInfo(purchaseContractList);
       return pageInfo;
   }

}
